package com.ttn.student.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import com.ttn.common.core.entity.Result;
import com.ttn.common.core.entity.business.CourseUnit;
import com.ttn.common.core.entity.business.converter.CourseUnitConverter;
import com.ttn.common.core.entity.studentrecord.LearningProgressRecord;
import com.ttn.common.core.entity.studentrecord.StudentRecord;
import com.ttn.common.core.entity.studentrecord.TestStudyRecord;
import com.ttn.common.core.entity.studentrecord.query.LearningProgressQuery;
import com.ttn.common.core.entity.studentrecord.query.UnitReportQuery;
import com.ttn.common.core.entity.studentrecord.vo.*;
import com.ttn.student.mapper.LearningProgressRecordMapper;
import com.ttn.student.openfeign.BusinessFeignService;
import com.ttn.student.service.LearningProgressRecordService;
import com.ttn.student.service.LearningProgressTimeRecordService;
import com.ttn.student.service.StudentRecordService;
import com.ttn.student.service.TestStudyRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
@Slf4j
public class LearningProgressRecordServiceImpl extends ServiceImpl<LearningProgressRecordMapper, LearningProgressRecord> implements LearningProgressRecordService {

    @Resource
    private LearningProgressRecordMapper learningProgressRecordMapper;
    @Resource
    private StudentRecordService studentRecordService;
    @Resource
    private BusinessFeignService businessFeignService;

    @Resource
    private TestStudyRecordService testStudyRecordService;
    @Resource
    private LearningProgressTimeRecordService learningProgressTimeRecordService;

    @Override
    public Result queryLearningProgress(LearningProgressQuery learningProgressQuery) {
        StudentRecord studentRecord = studentRecordService.getById(learningProgressQuery.getStudentId());
        LearningProgressVO learningProgressVO = new LearningProgressVO();
        learningProgressVO.setGrade(studentRecord.getGrade());
        learningProgressVO.setStudentId(studentRecord.getId());
        learningProgressVO.setLearningProgress(BigDecimal.ZERO);
        //获取当前学习记录
        LambdaQueryWrapper<LearningProgressRecord> learningProgressRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
        learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getStudentId, studentRecord.getId());
        learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getGrade, learningProgressQuery.getGrade());
        List<LearningProgressRecord> learningProgressRecordList = this.list(learningProgressRecordLambdaQueryWrapper);
        if (learningProgressRecordList.size() > 0) {
            Integer courseUnitNumberByGrade = businessFeignService.serviceQueryCourseUnitNumberByGrade(learningProgressQuery.getGrade()).getData();
            Integer sumCourseUnitNumber = testStudyRecordService.querySumCourseUnitNumber(learningProgressQuery.getGrade(), learningProgressQuery.getStudentId());
            learningProgressVO.setLearningProgress(NumberUtil.div(sumCourseUnitNumber, courseUnitNumberByGrade, 2));
        }
        List<LearningProgressDetailsVO> learningProgressDetailsVOList = Lists.newArrayList();
        List<CourseUnit> courseUnitList = businessFeignService.serviceQueryCourseUnitByGrade(learningProgressQuery.getGrade()).getData();
        learningProgressDetailsVOList = CourseUnitConverter.INSTANCE.CourseUnit2LearningProgressDetailsVOList(courseUnitList);
        if (learningProgressDetailsVOList.size() > 0) {
            AtomicInteger countEq = new AtomicInteger(0);
            learningProgressDetailsVOList.stream().forEach(learningProgressDetails -> {
                Optional<LearningProgressRecord> learningProgressRecordOptional = learningProgressRecordList.stream().filter(s -> s.getCourseUnitId().equals(learningProgressDetails.getId())).findFirst();
                if (learningProgressRecordOptional.isPresent()) {
                    LearningProgressRecord learningProgressRecord = learningProgressRecordOptional.get();
                    if (learningProgressRecord.getFinishFlag().equals(1)) {
                        learningProgressDetails.setCourseStatus(2);
                        if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.031)) == -1) {
                            learningProgressDetails.setStarRating(0);

                        } else if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.030)) == 1 && NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.061)) == -1) {
                            learningProgressDetails.setStarRating(1);
                        } else if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.060)) == 1 && NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.081)) == -1) {
                            learningProgressDetails.setStarRating(2);
                        } else if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.080)) == 1) {
                            learningProgressDetails.setStarRating(3);
                        }
                    } else {
                        learningProgressDetails.setCourseStatus(1);
                        countEq.set(1);
                    }

                } else {
                    if (studentRecord.getGrade() > learningProgressQuery.getGrade()) {
                        learningProgressDetails.setCourseStatus(1);

                    } else if (studentRecord.getGrade() == learningProgressQuery.getGrade() && countEq.get() == 0) {
                        countEq.set(1);
                        learningProgressDetails.setCourseStatus(1);
                    }
                }
            });

        }
        learningProgressVO.setLearningProgressDetails(learningProgressDetailsVOList);

        return Result.success(learningProgressVO);
    }

    @Override
    public Result queryHomeInformation(int studentId, HttpServletRequest request) {
        HomeInformationVO homeInformationVO = new HomeInformationVO();
        StudentRecord studentRecord = studentRecordService.getById(studentId);
        homeInformationVO.setId(studentRecord.getId());
        homeInformationVO.setNickName(studentRecord.getNickName());
        homeInformationVO.setStudentNum(studentRecord.getStudentNum());
        homeInformationVO.setStudentType(studentRecord.getStudentType());
        homeInformationVO.setCellPhoneNumber(studentRecord.getCellPhoneNumber());
        homeInformationVO.setPlanTime(studentRecord.getPlanTime());
        homeInformationVO.setGrade(studentRecord.getGrade());
        homeInformationVO.setStudentType(studentRecord.getStudentType());
        homeInformationVO.setLearningTime(learningProgressTimeRecordService.getTodayStudyTime(studentId));
        homeInformationVO.setUnitCoursesNumber(businessFeignService.serviceQueryCourseUnitNumberByGrade(studentRecord.getGrade()).getData());
        homeInformationVO.setLearningUnitCoursesNumber(testStudyRecordService.querySumCourseUnitNumber(studentRecord.getGrade(), studentId));
        List<LearningProgressDetailsVO> learningProgressDetailsVOList = Lists.newArrayList();
        if (studentRecord.getStudentType().equals(2)) {

            //获取当前学习记录
            LambdaQueryWrapper<LearningProgressRecord> learningProgressRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
            learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getStudentId, studentRecord.getId());
            learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getGrade, studentRecord.getGrade());
            List<LearningProgressRecord> learningProgressRecordList = this.list(learningProgressRecordLambdaQueryWrapper);
            List<CourseUnit> courseUnitList = businessFeignService.serviceQueryCourseUnitByGrade(studentRecord.getGrade()).getData();
            learningProgressDetailsVOList = CourseUnitConverter.INSTANCE.CourseUnit2LearningProgressDetailsVOList(courseUnitList);
            //判断是否有学习记录，如果有获取学习记录课程，就在课程中找到学习中的课程;如果没有直接获取改等级课程

            if (learningProgressRecordList.size() > 0) {
                AtomicInteger countEq = new AtomicInteger(0);
                learningProgressDetailsVOList.stream().forEach(learningProgressDetails -> {
                    Optional<LearningProgressRecord> learningProgressRecordOptional = learningProgressRecordList.stream().filter(s -> s.getCourseUnitId().equals(learningProgressDetails.getId())).findFirst();
                    if (learningProgressRecordOptional.isPresent()) {
                        LearningProgressRecord learningProgressRecord = learningProgressRecordOptional.get();
                        if (learningProgressRecord.getFinishFlag().equals(0)) {
                            countEq.set(1);
                            learningProgressDetails.setCourseStatus(1);
                        } else {
                            learningProgressDetails.setCourseStatus(2);
                            if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.031)) == -1) {
                                learningProgressDetails.setStarRating(0);

                            } else if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.030)) == 1 && NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.061)) == -1) {
                                learningProgressDetails.setStarRating(1);
                            } else if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.060)) == 1 && NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.081)) == -1) {
                                learningProgressDetails.setStarRating(2);
                            } else if (NumberUtil.div(learningProgressRecord.getCorrectAmount(), learningProgressRecord.getCourseUnitNum(), 3).compareTo(BigDecimal.valueOf(0.080)) == 1) {
                                learningProgressDetails.setStarRating(3);
                            }
                        }

                    } else {
                        if (countEq.get() == 0) {
                            learningProgressDetails.setCourseStatus(1);
                            countEq.set(1);

                        }
                    }
                });
            } else {
                log.info("没有学习记录，查询课程记录");
                if (learningProgressDetailsVOList.size() > 0) {
                    LearningProgressDetailsVO learningProgressDetailsVO = learningProgressDetailsVOList.get(0);
                    learningProgressDetailsVO.setCourseStatus(1);
                    learningProgressDetailsVOList.set(0, learningProgressDetailsVO);
                }
            }
            learningProgressDetailsVOList = learningProgressDetailsVOList.stream().filter(s -> !s.getCourseStatus().equals(2)).limit(2).collect(Collectors.toList());

            homeInformationVO.setCourseUnit(learningProgressDetailsVOList);
        }
        return Result.success(homeInformationVO);
    }

    @Override
    public Result queryLearningProgressByUnitId(int unitId, int studentId) {
        List<LearningProgressByUnitIdVO> learningProgressByUnitIdList = Lists.newArrayList();
        CourseUnit courseUnit = businessFeignService.serviceQueryCourseUnitByUnitId(unitId).getData();
        if (Objects.nonNull(courseUnit)) {
            List<String> unitTaskTypeList = Lists.newArrayList(Arrays.asList(courseUnit.getUnitTaskType().split(",")));
            List<TestStudyRecord> testStudyRecordList = testStudyRecordService.queryTestStudyRecordByUnitId(unitId, studentId);
            AtomicInteger countEq = new AtomicInteger(0);
            unitTaskTypeList.forEach(unitTaskType -> {
                LearningProgressByUnitIdVO learningProgressByUnitIdVO = new LearningProgressByUnitIdVO();
                learningProgressByUnitIdVO.setCourseUnitId(unitId);
                learningProgressByUnitIdVO.setUnitTaskType(Integer.valueOf(unitTaskType));
                Optional<TestStudyRecord> testStudyRecordOptional = testStudyRecordList.stream().filter(s -> s.getUnitTaskType().equals(unitTaskType)).findFirst();
                if (testStudyRecordOptional.isPresent()) {
                    if (testStudyRecordOptional.get().getScore() >= 60) {
                        learningProgressByUnitIdVO.setCourseStatus(3);
                    } else {
                        learningProgressByUnitIdVO.setCourseStatus(2);
                        countEq.set(1);
                    }
                } else {
                    LambdaQueryWrapper<TestStudyRecord> testStudyRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
                    testStudyRecordLambdaQueryWrapper.eq(TestStudyRecord::getUnitTaskType, unitTaskType);
                    testStudyRecordLambdaQueryWrapper.eq(TestStudyRecord::getCourseUnitId, unitId);
                    testStudyRecordLambdaQueryWrapper.eq(TestStudyRecord::getStudentId, studentId);
                    if (testStudyRecordService.count(testStudyRecordLambdaQueryWrapper) > 0) {
                        learningProgressByUnitIdVO.setCourseStatus(2);
                        countEq.set(1);
                    } else {
                        StudentRecord studentRecord = studentRecordService.getById(studentId);
                        Result<CourseUnit> courseUnitResult = businessFeignService.serviceQueryCourseUnitByUnitId(unitId);
                        if (studentRecord.getGrade() > courseUnitResult.getData().getGrade() && countEq.get() == 0) {
                            countEq.set(1);
                            learningProgressByUnitIdVO.setCourseStatus(1);

                        } else if (studentRecord.getGrade() == courseUnitResult.getData().getGrade() && countEq.get() == 0) {
                            countEq.set(1);
                            learningProgressByUnitIdVO.setCourseStatus(1);
                        } else {
                            learningProgressByUnitIdVO.setCourseStatus(0);
                        }
                    }
                }
                learningProgressByUnitIdList.add(learningProgressByUnitIdVO);
            });
            if (courseUnit.getGrade() < 6) {
                if (testStudyRecordList.size() == 4) {
                    if (learningProgressByUnitIdList.get(3).getCourseStatus().equals(3)) {
                        learningProgressByUnitIdList.get(3).setCourseStatus(2);
                        learningProgressByUnitIdList.get(3).setOralScoreStatus(1);
                    }
                } else if (testStudyRecordList.size() == 5) {
                    if (NumberUtil.div(NumberUtil.add(testStudyRecordList.get(3).getScore(), testStudyRecordList.get(4).getScore()), 2).compareTo(BigDecimal.valueOf(60)) > -1) {
                        learningProgressByUnitIdList.get(3).setCourseStatus(3);
                        learningProgressByUnitIdList.get(3).setOralScoreStatus(2);
                    } else {
                        learningProgressByUnitIdList.get(3).setCourseStatus(2);
                        learningProgressByUnitIdList.get(3).setOralScoreStatus(1);
                    }
                }
            }

        }

        return Result.success(learningProgressByUnitIdList);
    }

    @Override
    public Result queryUnitReport(UnitReportQuery unitReportQuery) {
        UnitReportVO unitReportVO = new UnitReportVO();
        StudentRecord studentRecord = studentRecordService.getById(unitReportQuery.getStudentId());
        if (Objects.nonNull(studentRecord)) {
            unitReportVO.setStudentGrade(studentRecord.getGrade());
        }
        List<TestStudyRecord> testStudyRecordList = Lists.newArrayList();
        if (unitReportQuery.getQueryHistory().equals(0)) {
            QueryWrapper<TestStudyRecord> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("student_id", unitReportQuery.getStudentId()).eq("course_unit_id", unitReportQuery.getCourseUnitId()).groupBy("course_unit_id", "student_id", "unit_task_type").select("id", "course_unit_id", "student_id", "score", "unit_task_type", "finish_flag", "study_num", "beyond_proportion", "grade", "create_time", "correct_amount", "course_unit_num", "MAX(create_time) AS latest_create_time");
            queryWrapper.inSql("create_time", "SELECT MAX(create_time) FROM test_study_record GROUP BY course_unit_id, student_id, unit_task_type");
            testStudyRecordList = testStudyRecordService.list(queryWrapper);

        } else {
            testStudyRecordList = testStudyRecordService.queryUnitReport(unitReportQuery);
        }
        if (testStudyRecordList.size() > 0) {
//            单元任务(1词汇2听力3语法4口语跟读 5 口语会话)
            List<TestStudyRecord> finalTestStudyRecordList = testStudyRecordList;
            testStudyRecordList.stream().forEach(testStudyRecord -> {
                if (testStudyRecord.getUnitTaskType().equals("1")) {
                    unitReportVO.setVocabularyRating(getRating(testStudyRecord.getScore()));

                } else if (testStudyRecord.getUnitTaskType().equals("2")) {
                    unitReportVO.setHearingRating(getRating(testStudyRecord.getScore()));
                } else if (testStudyRecord.getUnitTaskType().equals("3")) {
                    unitReportVO.setGrammarRating(getRating(testStudyRecord.getScore()));
                } else if (testStudyRecord.getUnitTaskType().equals("4")) {
                    if (finalTestStudyRecordList.size() == 5) {
                        unitReportVO.setSpeakingRating(getRating((testStudyRecord.getScore() + finalTestStudyRecordList.get(4).getScore()) / 2));
                    } else {
                        unitReportVO.setSpeakingRating(getRating(testStudyRecord.getScore()));
                    }
                }
            });
            Result<List<CourseUnit>> courseUnitResult = businessFeignService.serviceQueryCourseUnitByGrade(testStudyRecordList.get(0).getGrade());
            AtomicInteger nextCourseUnitId = new AtomicInteger(-1);
            if (courseUnitResult.isSuccess() && courseUnitResult.getData().size() > 0) {
                courseUnitResult.getData().forEach(courseUnit -> {
                    if (nextCourseUnitId.get() == 0) {
                        unitReportVO.setNextCourseUnitId(courseUnit.getId());
                        nextCourseUnitId.set(-1);
                        unitReportVO.setCourseUnitGrade(courseUnit.getGrade());
                        unitReportVO.setNextCourseUnitName(courseUnit.getCourseUnitName());
                        unitReportVO.setNextCourseUnitTitle(courseUnit.getTitle());
                    }
                    if (courseUnit.getId().equals(unitReportQuery.getCourseUnitId())) {
                        unitReportVO.setCourseUnitName(courseUnit.getCourseUnitName());
                        nextCourseUnitId.set(0);
                    }
                });
            }
            if (nextCourseUnitId.get() == 0) {
                courseUnitResult = businessFeignService.serviceQueryCourseUnitByGrade(testStudyRecordList.get(0).getGrade() + 1);
                if (courseUnitResult.isSuccess() && courseUnitResult.getData().size() > 0) {
                    courseUnitResult.getData().forEach(courseUnit -> {
                        if (nextCourseUnitId.get() == 0) {
                            unitReportVO.setNextCourseUnitId(courseUnit.getId());
                            nextCourseUnitId.set(-1);
                            unitReportVO.setCourseUnitGrade(courseUnit.getGrade());
                            unitReportVO.setNextCourseUnitName(courseUnit.getCourseUnitName());
                            unitReportVO.setNextCourseUnitTitle(courseUnit.getTitle());
                        }
                    });

                }
            }


            unitReportVO.setCourseUnitStarRating(getRating(testStudyRecordList.stream().mapToInt(TestStudyRecord::getScore).sum() / testStudyRecordList.size()));

        }
        return Result.success(unitReportVO);
    }

    @Override
    public int queryJudgeGrade(int studentId) {
        //judgeGrade=0,不可以升级
        AtomicInteger judgeGrade = new AtomicInteger(1);
        StudentRecord studentRecord = studentRecordService.getById(studentId);
        if (Objects.nonNull(studentRecord)) {
            Result<List<CourseUnit>> listResult = businessFeignService.serviceQueryCourseUnitByGrade(studentRecord.getGrade());
            if (listResult.isSuccess() && listResult.getData().size() > 0) {
                LambdaQueryWrapper<LearningProgressRecord> learningProgressRecordLambdaQueryWrapper = new LambdaQueryWrapper<>();
                learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getGrade, studentRecord.getGrade());
                learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getStudentId, studentRecord.getId());
                learningProgressRecordLambdaQueryWrapper.eq(LearningProgressRecord::getFinishFlag, 1);
                List<LearningProgressRecord> learningProgressRecordList = this.list(learningProgressRecordLambdaQueryWrapper);
                if (learningProgressRecordList.size() > 0) {
                    listResult.getData().stream().forEach(courseUnit -> {

                        List<LearningProgressRecord> progressRecordList = learningProgressRecordList.stream().filter(s -> s.getCourseUnitId().equals(courseUnit.getId())).collect(Collectors.toList());

                        if (progressRecordList.size() == 0) {
                            judgeGrade.set(0);
                        }
                    });
                    //全部匹配,可以升级
                    if (judgeGrade.get() == 1) {
                        if (studentRecord.getGrade() < 12) {
                            studentRecord.setGrade(studentRecord.getGrade() + 1);
                            studentRecordService.updateById(studentRecord);
                        }
                    }
                }

            }

        }

        return judgeGrade.get();
    }


    int getRating(Integer score) {
        int rating = 0;
        if (score < 30) {
            rating = 0;
        } else if (30 <= score && score < 60) {
            rating = 1;
        } else if (60 <= score && score < 80) {
            rating = 2;
        } else if (score > 80) {
            rating = 3;
        }
        return rating;
    }
}
